{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "authorship_tag": "ABX9TyN20zedRXnzXoBHtm67HhsU",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/tomasonjo/blogs/blob/master/llm/llama_diffbot_agent.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "71UA4gDQxKSd",
        "outputId": "a47efbd9-6fab-4de3-d86e-353d2f5e3c01"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/302.0 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[90m╺\u001b[0m \u001b[32m297.0/302.0 kB\u001b[0m \u001b[31m20.0 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m302.0/302.0 kB\u001b[0m \u001b[31m7.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.6/1.6 MB\u001b[0m \u001b[31m23.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m15.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.5/1.5 MB\u001b[0m \u001b[31m41.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m176.8/176.8 kB\u001b[0m \u001b[31m10.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m298.0/298.0 kB\u001b[0m \u001b[31m16.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m43.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.5/49.5 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ],
      "source": [
        "!pip install --quiet llama-index neo4j"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "import getpass\n",
        "from llama_index.core.tools import FunctionTool\n",
        "from typing import Annotated, List, Optional, Dict\n",
        "from neo4j import GraphDatabase\n",
        "from pydantic import Field\n",
        "from llama_index.core.agent import AgentRunner\n",
        "from llama_index.llms.openai import OpenAI"
      ],
      "metadata": {
        "id": "FA0rTP-dsCi7"
      },
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "graph = GraphDatabase.driver(\n",
        "    \"neo4j+s://diffbot.neo4jlabs.com:7687\",\n",
        "    auth=(getpass.getpass(\"Diffbot username:\"), getpass.getpass(\"Diffbot password:\")),\n",
        ")\n",
        "\n",
        "def database_query(query: str, params: Dict = {}, database: str = \"companies\") -> List[Dict]:\n",
        "    data = graph.execute_query(query, database_=database, **params)\n",
        "    return [el.data() for el in data.records]"
      ],
      "metadata": {
        "id": "pytzcp3_0Q7v",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "13e34f28-3719-4362-c40f-fd831615c0e9"
      },
      "execution_count": 5,
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Diffbot username:··········\n",
            "Diffbot password:··········\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "7tYv9lPDyOW-",
        "outputId": "f2698001-d34b-409f-b7bd-f23a4e108429"
      },
      "execution_count": 6,
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "OpenAI API Key:··········\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "def remove_lucene_chars(text: str) -> str:\n",
        "    \"\"\"Remove Lucene special characters\"\"\"\n",
        "    special_chars = [\n",
        "        \"+\",\n",
        "        \"-\",\n",
        "        \"&\",\n",
        "        \"|\",\n",
        "        \"!\",\n",
        "        \"(\",\n",
        "        \")\",\n",
        "        \"{\",\n",
        "        \"}\",\n",
        "        \"[\",\n",
        "        \"]\",\n",
        "        \"^\",\n",
        "        '\"',\n",
        "        \"~\",\n",
        "        \"*\",\n",
        "        \"?\",\n",
        "        \":\",\n",
        "        \"\\\\\",\n",
        "    ]\n",
        "    for char in special_chars:\n",
        "        if char in text:\n",
        "            text = text.replace(char, \" \")\n",
        "    return text.strip()\n",
        "\n",
        "def generate_full_text_query(input: str) -> str:\n",
        "    \"\"\"\n",
        "    Generate a full-text search query for a given input string.\n",
        "\n",
        "    This function constructs a query string suitable for a full-text search.\n",
        "    It processes the input string by splitting it into words and appending a\n",
        "    similarity threshold (~2) to each word, then combines them using the AND\n",
        "    operator. Useful for mapping movies and people from user questions\n",
        "    to database values, and allows for some misspelings.\n",
        "    \"\"\"\n",
        "    full_text_query = \"\"\n",
        "    words = [el for el in remove_lucene_chars(input).split() if el]\n",
        "    for word in words[:-1]:\n",
        "        full_text_query += f\" {word}~2 AND\"\n",
        "    full_text_query += f\" {words[-1]}~2\"\n",
        "    return full_text_query.strip()\n",
        "\n",
        "\n",
        "candidate_query = \"\"\"\n",
        "CALL db.index.fulltext.queryNodes($index, $fulltextQuery, {limit: $limit})\n",
        "YIELD node\n",
        "RETURN coalesce(node.name, node.fullName) AS candidate,\n",
        "       node.id AS id,\n",
        "       labels(node)[0] AS label\n",
        "ORDER BY node.importance DESC\n",
        "\"\"\"\n",
        "\n",
        "\n",
        "def get_candidates(input: str, limit: int = 3) -> List[Dict[str, str]]:\n",
        "    \"\"\"\n",
        "    Retrieve a list of candidate entities from database based on the input string.\n",
        "\n",
        "    This function queries the Neo4j database using a full-text search. It takes the\n",
        "    input string, generates a full-text query, and executes this query against the\n",
        "    specified index in the database.\n",
        "    \"\"\"\n",
        "    ft_query = generate_full_text_query(input)\n",
        "    candidates = database_query(\n",
        "        candidate_query, {\"fulltextQuery\": ft_query, \"index\": \"org_name_fulltext\", \"limit\": limit}\n",
        "    )\n",
        "    return candidates\n"
      ],
      "metadata": {
        "id": "dA150VLRwDIt"
      },
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "get_candidates(\"Neo4j\")"
      ],
      "metadata": {
        "id": "cdtqHuq7veT9",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "664804b0-4b25-4ce8-8e52-616ff34b65b6"
      },
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[{'candidate': 'Neo4j',\n",
              "  'id': 'https://diffbot.com/entity/Ee3Wn9kzHNf2TmXB0gpqx-w',\n",
              "  'label': 'Organization'},\n",
              " {'candidate': 'neo42',\n",
              "  'id': 'https://diffbot.com/entity/Ezf5spJoqP6qCbL9Ha3iX4w',\n",
              "  'label': 'Organization'},\n",
              " {'candidate': 'Neo4T',\n",
              "  'id': 'https://diffbot.com/entity/EUjppqZXPMZW3CqsbqRG0KQ',\n",
              "  'label': 'Organization'}]"
            ]
          },
          "metadata": {},
          "execution_count": 8
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "info_cypher_query = \"\"\"\n",
        "MATCH (o:Organization {id: $org_id})\n",
        "RETURN apoc.map.removeKey(properties(o), 'embedding') AS properties,\n",
        "      [(o)-[:PARTNERSHIP]-(r) | r.name][..10] AS partners,\n",
        "      [(o)-[:HAS_SUBSIDIARY]->(r) | r.name][..10] AS subsidiaries,\n",
        "      [(o)-[:HAS_SUPPLIER]->(r) | r.name][..10] AS suppliers,\n",
        "      [(o)-[:HAS_COMPETITOR]-(r) | r.name][..10] AS competitor,\n",
        "      [(o)-[:BOARD_MEMBER]->(r) | r.name][..10] AS board_members,\n",
        "      [(o)-[:HAS_CEO]->(r) | r.name][..10] AS ceo\n",
        "\"\"\"\n",
        "\n",
        "\n",
        "def get_company_information(\n",
        "    company: str = Field(\n",
        "        description=\"The specified company for retrieving the latest news\"\n",
        "    )\n",
        ") -> str:\n",
        "    candidates = get_candidates(company, limit=3)\n",
        "    if not candidates:\n",
        "        return \"No organization found\"\n",
        "    if len(candidates) == 1 or candidates[0][\"candidate\"] == company:\n",
        "        org_id = candidates[0][\"id\"]\n",
        "    else:\n",
        "        return (\"Which of these organizations do you mean? \"\n",
        "        f\"Here are the options: {[el['candidate'] for el in candidates]}\")\n",
        "    info = database_query(info_cypher_query, {\"org_id\": org_id}, database=\"companies\")\n",
        "    if not info:\n",
        "        return \"Couldn't find any news\"\n",
        "    return info\n",
        "\n",
        "info_description = \"\"\"Useful for getting the information about specific organization.\"\"\"\n",
        "\n",
        "info_tool = FunctionTool.from_defaults(get_company_information, description=info_description)"
      ],
      "metadata": {
        "id": "WuSqVZ9NOPqz"
      },
      "execution_count": 9,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def map_type(type:str) -> str:\n",
        "    if type == \"supplier\":\n",
        "        return \"-[:HAS_SUPPLIER]->\"\n",
        "    elif type == \"partnership\":\n",
        "        return \"-[:PARTNERSHIP]-\"\n",
        "    elif type == \"subsidiary\":\n",
        "        return \"-[:HAS_SUBSIDIARY]->\"\n",
        "    elif type == \"competitor\":\n",
        "        return \"-[:HAS_COMPETITOR]-\"\n",
        "\n",
        "def get_latest_news(\n",
        "    company: str = Field(\n",
        "        description=\"The specified company for retrieving the latest news\"\n",
        "    ),\n",
        "    related_entities: Annotated[\n",
        "        Optional[str],\n",
        "        Field(\n",
        "            default=None,\n",
        "            description=\"Specifies whether to include news about entities related to the specified company, such as competitors, suppliers, or partners.\",\n",
        "            enum=[\"supplier\", \"partnership\", \"subsidiary\", \"competitor\"],\n",
        "        )\n",
        "    ] = None,\n",
        ") -> str:\n",
        "    candidates = get_candidates(company, limit=3)\n",
        "    if not candidates:\n",
        "        return \"No organization found\"\n",
        "    if len(candidates) == 1 or candidates[0][\"candidate\"] == company:\n",
        "        org_id = candidates[0][\"id\"]\n",
        "    else:\n",
        "        return (\"Which of these organizations do you mean? \"\n",
        "        f\"Here are the options: {[el['candidate'] for el in candidates]}\")\n",
        "\n",
        "    cypher_query = \"\"\n",
        "    # Get ids of related entities\n",
        "    if related_entities:\n",
        "        cypher_query += f\"\"\"CALL () {{\n",
        "\tUSE diffbot.companies\n",
        "  MATCH (o:Organization {{id: $org_id}}){map_type(related_entities)}(related_entities)\n",
        "        RETURN collect(related_entities.id) AS org_ids\n",
        "  }} \"\"\"\n",
        "    else: # Otherwise just use the org id\n",
        "        cypher_query += \"WITH [$org_id] AS org_ids \"\n",
        "\n",
        "    cypher_query += \"\"\"\n",
        "    CALL (org_ids) {\n",
        "      USE diffbot.articles\n",
        "        OPTIONAL MATCH (c)<-[:HAS_CHUNK]-(a:Article)-[:HAS_TAG]->(t:Tag)\n",
        "        WHERE t.id IN org_ids\n",
        "        RETURN a.title AS title, c.text AS text, t.label AS related_org ORDER BY a.date DESC LIMIT 5\n",
        "      }\n",
        "    RETURN title, text, related_org\"\"\"\n",
        "    news = database_query(cypher_query, {\"org_id\": org_id}, database=\"diffbot\")\n",
        "    if not news:\n",
        "        return \"Couldn't find any news\"\n",
        "    return news\n",
        "\n",
        "news_description = \"\"\"Useful for getting the latest news about specific organization or their related entities.\"\"\"\n",
        "\n",
        "news_tool = FunctionTool.from_defaults(get_latest_news, description=news_description)"
      ],
      "metadata": {
        "id": "SK22Lfm7PEHx"
      },
      "execution_count": 10,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "tools = [news_tool, info_tool]"
      ],
      "metadata": {
        "id": "X0hgPBHut5-A"
      },
      "execution_count": 11,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "llm = OpenAI(model=\"gpt-4\")\n",
        "\n",
        "system_prompt = \"\"\"\n",
        "You are a helpful assistant.\n",
        "Your job is to find information using available tools and then use that information to generate the final answer.\n",
        "Never answer with any information that isn't provided by the tools!\n",
        "Always trust the tool output, even if it might not be completely related to question!\n",
        "If the tool asks for a follow up question, ask the user that!\"\"\""
      ],
      "metadata": {
        "id": "8jMT6n-sxep2"
      },
      "execution_count": 12,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "agent = AgentRunner.from_llm(\n",
        "    llm=llm,\n",
        "    tools=tools,\n",
        "    system_prompt=system_prompt,\n",
        "    verbose=True,\n",
        ")"
      ],
      "metadata": {
        "id": "KXHxjZ_Dxk04"
      },
      "execution_count": 13,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "response = agent.chat(\"Who are the board members of Neo4j?\")\n",
        "print(response.response)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "8ZrP56mYPtN7",
        "outputId": "754d9dbc-de8d-428d-f892-386576fd6983"
      },
      "execution_count": 14,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Added user message to memory: Who are the board members of Neo4j?\n",
            "=== Calling Function ===\n",
            "Calling function: get_company_information with args: {\n",
            "  \"company\": \"Neo4j\"\n",
            "}\n",
            "Got output: [{'properties': {'summary': 'Software solution provider', 'isAcquired': False, 'facebookUri': 'facebook.com/neo4j.graph.database', 'totalInvestment': 755100032.0, 'blogUri': 'blog.neo4j.org', 'id': 'https://diffbot.com/entity/Ee3Wn9kzHNf2TmXB0gpqx-w', 'homepageUri': 'neo4j.com', 'description': \"Neo Technology is the NOSQL database company for the enterprise. Neo4j is a robust, high performance, scalable graph database. Neo Technology is the industry's only NOSQL database that solves the complex, connected data challenges that enterprises face today. Proven by eight years of 24/7 production use, Neo4j is a fully transactional database, which enables customers, including Adobe and Cisco, to tackle complex data problems. Neo Technology is a privately held company funded by Fidelity Growth Partners Europe, Sunstone Capital and Conor Venture Partners, and is headquartered in Menlo Park, CA.\", 'nbEmployees': 910, 'name': 'Neo4j', 'angellistUri': 'angel.co/neo-technology', 'linkedInUri': 'linkedin.com/company/neo4j', 'totalInvestmentCurrency': 'USD', 'twitterUri': 'twitter.com/neo4j', 'revenue': 240000000.0, 'secCentralIndexKeys': ['1529484', '1759144'], 'isDissolved': False, 'logo': 'https://kg.diffbot.com/image/api/get?fetch=yes&url=g%3Cj7P0Stx9f%3CJ.LjzD%7C.X%7DY%3C7Y%3Djj7Y0Dwj%7BQVFf%3CKhSRKIy8b85Lm%2F%5Cp%3C%5B9Z-DhvGeYm6C7KdAcxCvJ%5ExNu8V0Pi2YivI%3CCNtUn%3Cuyr%7DEvJ%5DzSw%3BW%26Er%60Aqt%26%7Eh%5CW5L%60%3CzLf%3BD%3Ez8L%5DxLGfJuW1%3CS%7Bcza%7C%5Ed%3Fz%7C7%3CCfPJC', 'nbUniqueInvestors': 17, 'crunchbaseUri': 'crunchbase.com/organization/neo-technology', 'foundingDate': neo4j.time.DateTime(2007, 1, 1, 0, 0, 0, 0), 'isPublic': False, 'importance': 79.87448120117188, 'monthlyTraffic': 275618.0, 'fullName': 'Neo4j, Inc.', 'revenueCurrency': 'USD', 'isNonProfit': False}, 'partners': ['Google', 'Microsoft', 'IBM', 'Alibaba Group', 'Amazon Web Services (AWS)', 'eBay', 'Google Cloud', 'Deloitte', 'Snowflake', 'Vertex.AI'], 'subsidiaries': ['Distributed Technology Associates'], 'suppliers': ['streamlinevents', 'eQ Technologic', 'Hevo Data', 'Klue', 'Slide UX', 'DeftBOX Solutions', 'CK Hutchison Holdings', 'AtomicJar', 'Testcontainers', 'Day5 Analytics'], 'competitor': ['TigerGraph', 'Aerospike', 'TigerGraph', 'Aerospike'], 'board_members': ['Patrick Pichette', 'Rod Johnson', 'Eric Ries', 'Christian Jepsen', 'Johan Brenner', 'Gaurav Tuli', 'nathalie bruls', 'Denise Persson', 'Emanuel Lang', 'Magnus Christerson'], 'ceo': ['Emil Eifrem']}]\n",
            "========================\n",
            "\n",
            "The board members of Neo4j are:\n",
            "\n",
            "1. Patrick Pichette\n",
            "2. Rod Johnson\n",
            "3. Eric Ries\n",
            "4. Christian Jepsen\n",
            "5. Johan Brenner\n",
            "6. Gaurav Tuli\n",
            "7. Nathalie Bruls\n",
            "8. Denise Persson\n",
            "9. Emanuel Lang\n",
            "10. Magnus Christerson\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "response = agent.chat(\"What's the latest news about Neo4j?\")\n",
        "response.response"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 252
        },
        "id": "62-ZQAkwyBpd",
        "outputId": "dac12d23-adcd-4903-b469-99744a9d84a3"
      },
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Added user message to memory: What's the latest news about Neo4j?\n",
            "=== Calling Function ===\n",
            "Calling function: get_latest_news with args: {\n",
            "  \"company\": \"Neo4j\"\n",
            "}\n",
            "Got output: [{'title': 'Neo4j Connections: Go From GenAI Pilot to Production Faster With a Knowledge Graph', 'text': 'Without knowledge graphs, you could face massive challenges as you look to transition your GenAI project from pilot to production. Knowledge graphs change all that.\\nWith knowledge graphs, your GenAI project can avoid hallucinations and offer better predictions and insights. How do knowledge graphs provide the best, fastest path to move GenAI projects forward? They integrate seamlessly with systems and connect data across sources. They map relationships and improve search.\\nWant to learn more? Don’t miss this virtual, half-day event, where industry experts will provide:\\nReal-world insights on how to move GenAI from pilot to production\\nA look at the enhanced search and data integration capabilities of knowledge graphs\\nCustomer success stories, including details on tech stacks, data modeling, and optimization\\nAn overview of how Neo4j knowledge graphs address your GenAI project’s need for enhanced accuracy, explainability, and scalability\\nThis is your opportunity to hear how companies are implementing GenAI successfully.\\nSign up today to get the agenda and speaker details as they become available. You’ll also get access to the on-demand sessions after the event.', 'related_org': 'Neo4j'}, {'title': 'Neo4j Connections: Go From GenAI Pilot to Production Faster With a Knowledge Graph', 'text': 'Without knowledge graphs, you could face massive challenges as you look to transition your GenAI project from pilot to production. Knowledge graphs change all that.\\nWith knowledge graphs, your GenAI project can avoid hallucinations and offer better predictions and insights. How do knowledge graphs provide the best, fastest path to move GenAI projects forward? They integrate seamlessly with systems and connect data across sources. They map relationships and improve search.\\nWant to learn more? Don’t miss this virtual, half-day event, where industry experts will provide:\\nReal-world insights on how to move GenAI from pilot to production\\nA look at the enhanced search and data integration capabilities of knowledge graphs\\nCustomer success stories, including details on tech stacks, data modeling, and optimization\\nAn overview of how Neo4j knowledge graphs address your GenAI project’s need for enhanced accuracy, explainability, and scalability\\nThis is your opportunity to hear how companies are implementing GenAI successfully.\\nSign up today to get the agenda and speaker details as they become available. You’ll also get access to the on-demand sessions after the event.', 'related_org': 'Neo4j'}, {'title': 'Neo4j Connections: Go From GenAI Pilot to Production Faster With a Knowledge Graph', 'text': 'Without knowledge graphs, you could face massive challenges as you look to transition your GenAI project from pilot to production. Knowledge graphs change all that.\\nWith knowledge graphs, your GenAI project can avoid hallucinations and offer better predictions and insights. How do knowledge graphs provide the best, fastest path to move GenAI projects forward? They integrate seamlessly with systems and connect data across sources. They map relationships and improve search.\\nWant to learn more? Don’t miss this virtual, half-day event, where industry experts will provide:\\nReal-world insights on how to move GenAI from pilot to production\\nA look at the enhanced search and data integration capabilities of knowledge graphs\\nCustomer success stories, including details on tech stacks, data modeling, and optimization\\nAn overview of how Neo4j knowledge graphs address your GenAI project’s need for enhanced accuracy, explainability, and scalability\\nThis is your opportunity to hear how companies are implementing GenAI successfully.', 'related_org': 'Neo4j'}]\n",
            "========================\n",
            "\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'The latest news about Neo4j is about their upcoming virtual, half-day event titled \"Neo4j Connections: Go From GenAI Pilot to Production Faster With a Knowledge Graph\". The event will focus on the benefits of using knowledge graphs in GenAI projects, including better predictions, insights, and improved search. The event will feature real-world insights on how to transition GenAI projects from pilot to production, an overview of the enhanced search and data integration capabilities of knowledge graphs, customer success stories, and an overview of how Neo4j knowledge graphs can enhance the accuracy, explainability, and scalability of GenAI projects. Attendees will also have the opportunity to hear how companies are successfully implementing GenAI.'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 15
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "response = agent.chat(\"What's the latest news about Neo4j partners?\")\n",
        "response.response"
      ],
      "metadata": {
        "id": "nl0o1YjTzcBk",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 306
        },
        "outputId": "fb977413-db7d-465f-e413-a1bf5c790c15"
      },
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Added user message to memory: What's the latest news about Neo4j partners?\n",
            "=== Calling Function ===\n",
            "Calling function: get_latest_news with args: {\n",
            "  \"company\": \"Neo4j\",\n",
            "  \"related_entities\": \"partnership\"\n",
            "}\n",
            "Got output: [{'title': 'Vatican and Microsoft Launch AI-Generated St Peter Basilica', 'text': '. Moreover, this digital model allows anyone to “visit” the basilica and discover its rich history from anywhere.\\n3D model captures 22 petabytes of data, equal to five million DVDs\\nThe highly detailed 3D model, built in partnership with digital preservation firm Iconem, holds a massive 22 petabytes of data—equivalent to about five million DVDs, according to Microsoft’s president.\\nThis technology has already uncovered structural issues, like missing mosaic pieces and tiny cracks, which are invisible to the human eye, with speed and accuracy that surpass human abilities.\\nPope Francis has encouraged the responsible use of AI. In his annual Peace Message, he called for an international agreement to ensure technology aligns with human values like compassion, mercy, and morality. He warned that technology without these principles could lead to serious risks.\\nOn Monday, Pope Francis expressed gratitude to the Microsoft team and basilica staff involved in the project. Moreover, he admired how modern technology is being used to share an ancient faith and protect a world heritage landmark, which will mark the 400th anniversary of its consecration in 2026.', 'related_org': 'Microsoft'}, {'title': 'Vatican and Microsoft Launch AI-Generated St Peter Basilica', 'text': 'On Monday, the Vatican and Microsoft introduced a new AI-generated version of St. Peter’s Basilica, allowing people to explore this historic site in a unique way. This digital model uses smart technology to help visitors look around the basilica while assisting the Vatican in managing crowds and spotting areas that may need repair.\\nTo create this digital replica, over 400,000 high-quality photos were taken using drones, cameras, and lasers. These images were collected in four weeks when the basilica was empty.\\nThis virtual version will be available online along with two new exhibits inside the basilica, offering both online and in-person visitors an interactive experience of one of the world’s most famous landmarks.\\n“It is literally one of the most technologically advanced and sophisticated projects of its kind that has ever been pursued,” Microsoft’s president Brad Smith told a Vatican press conference.\\nDigital access to St. Peter’s Basilica to welcome millions for 2025 Jubilee\\nThe project launched in time for the Vatican’s 2025 Jubilee, a sacred year when over 30 million pilgrims are expected to enter St. Peter’s Basilica through its Holy Door. This is in addition to the 50,000 people who already visit daily.\\nPope Francis, speaking to the project’s developers and Microsoft’s president, expressed his hopes: “Everyone, really everyone should feel welcome in this great house.”\\nPetros Eni Octagon, la segunda parte de la muestra inmersiva que podrá verse en la Basílica de San Pedro, realizada con IA por @Microsoft @iconem #wow pic.twitter.com/6ELyK6ZdpN\\n— Elisabetta Piqué (@bettapique) November 11, 2024\\nWith this digital platform, visitors can now book entry times, a new option for one of the world’s busiest sites. This could help reduce the long lines that typically form outside the basilica as tourists wait to enter.\\nAt the core of the project is a digital twin of St. Peter’s Basilica, created using advanced imaging techniques and smart technology. Moreover, this digital model allows anyone to “visit” the basilica and discover its rich history from anywhere.\\n3D model captures 22 petabytes of data, equal to five million DVDs\\nThe highly detailed 3D model, built in partnership with digital preservation', 'related_org': 'Microsoft'}, {'title': \"Google's Vids AI video maker is rolling out to most Workspace tiers\", 'text': 'Google\\nWe’re in a new age of AI now. Google has an AI video maker available on select Workspace editions.\\nGoogle Vids runs on Google’s AI model Gemini to create workplace and marketing videos from Google Drive files and descriptions. You can either start a video from scratch or use a pre-made template to get a first draft going. There’s even a “Help me create” option in which Gemini can suggest scripts to get you started on your video.\\nYou aren’t just limited to what’s in the templates. Google Vids allows you to use your own photos and videos. It also has a virtual recording studio so you can add your own photos and videos, record videos of yourself or just make audio tracks of your voice to accompany your video.\\nGoogle announced its new AI video making feature in April using the Gemini AI ...\\nCopyright of this story solely belongs to Engadget . To see the full text click HERE', 'related_org': 'Google'}, {'title': 'Google’s November Pixel update is rolling out', 'text': 'Pixel owners will get a notification when this snooze of an update is available.\\nSam Rutherford for Engadget\\nThe November update for Google Pixel devices running Android 15 is rolling out now. This batch doesn’t include exciting new features, like the AI-powered theft protection in the October update, but it has bug fixes and the latest security patches to tighten things up.\\nThe new software includes fixes for known intermittent issues with Bluetooth range, camera tilt when zooming between cameras and unexpected flashing or flickering of white dots or screen brightness. It also has fixes for adaptive brightness not activating, the keyboard dismiss button not working correctly and the performance and stability of some UI transitions and animations.\\nAndroid 15 arrived last month for Pixel devices, following the Pixel 9 lineup’s debut in August. The annual software jump focuses on security and privacy, like AI-powered theft detection lock ...\\nCopyright of this story solely belongs to Engadget . To see the full text click HERE', 'related_org': 'Google'}, {'title': 'Watch out, Windows Notepad users: Here comes AI', 'text': \"Were you thinking Microsoft has added AI to virtually its entire software lineup except for Notepad? Well, here comes an update to prove you wrong.\\nNow rolling out to Windows Insiders in Windows 11 is a new Rewrite option for Notepad that promises to spruce up your text with the help of AI. Using an AI model called GPT, Rewrite can revise sentences, modify the tone, or alter the length of your text, explains Microsoft.\\nAlso: Microsoft's Copilot AI is coming to your Office apps - whether you like it or not\\nTo take Rewrite for a spin, you'll need the latest Canary or Dev build on Windows 11. Assuming you're already registered with the Windows Insider program with either of these builds, head to Settings, select Windows Update, and click the button for Check for Updates.\\nYou should also make sure you're running the latest ...\\nCopyright of this story solely belongs to zdnet.com . To see the full text click HERE\", 'related_org': 'Microsoft'}]\n",
            "========================\n",
            "\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "\"Here are the latest news about Neo4j's partners:\\n\\n1. Microsoft has partnered with the Vatican to launch an AI-generated version of St. Peter’s Basilica. This digital model uses smart technology to help visitors explore the basilica and assists the Vatican in managing crowds and spotting areas that may need repair. The project was launched in time for the Vatican’s 2025 Jubilee.\\n\\n2. Google has rolled out an AI video maker available on select Workspace editions. Google Vids runs on Google’s AI model Gemini to create workplace and marketing videos from Google Drive files and descriptions. Users can start a video from scratch or use a pre-made template.\\n\\n3. Google's November update for Pixel devices running Android 15 is rolling out now. This update includes bug fixes and the latest security patches.\\n\\n4. Microsoft is rolling out a new Rewrite option for Notepad to Windows Insiders in Windows 11. The Rewrite option uses an AI model called GPT to revise sentences, modify the tone, or alter the length of text.\""
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 16
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "JTT1JUtZCBBN"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}